import VuexPersistence from 'vuex-persist'
import global from '../global'

const promisify = fn => options =>
  new Promise((resolve, reject) => {
    fn({
      ...options,
      success: resolve,
      fail: reject
    })
  })

const setStorage = promisify(global.setStorage)
const getStorage = global.getStorageSync
const removeStorage = promisify(global.removeStorage)
const clearStorage = promisify(global.clearStorage)

const storage = {
  keyIndex: [],
  getItem(key) {
    return getStorage(key)
  },
  setItem(key, data) {
    if (!this.keyIndex.includes(key)) {
      this.keyIndex.push(key)
    }
    return setStorage({ key, data })
  },
  removeItem(key) {
    this.keyIndex.splice(this.keyIndex.indexOf(key), 1)
    removeStorage({ key })
  },
  clear() {
    return clearStorage()
  },
  length() {
    return Promise.resolve(this.keyIndex.length)
  },
  key(keyIndex) {
    return Promise.resolve(this.keyIndex(keyIndex))
  }
}

function Persistence(options) {
  const vp = new VuexPersistence(options)
  this.options = options
  this.vp = vp

  async function plugin(store) {
    const hooks = (this.options && this.options.hooks) || {}
    try {
      if (typeof hooks.beforeRestore === 'function') {
        hooks.beforeRestore(store)
      }
    } catch (e) {} // eslint-disable-line

    await this.vp.plugin(store)

    try {
      if (typeof hooks.afterRestore === 'function') {
        hooks.afterRestore(store)
      }
    } catch (e) {} // eslint-disable-line
  }

  this.plugin = plugin.bind(this)
}

export { storage }

export default Persistence
